#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
#include <signal.h>
#include <sys/stat.h>

#include "debug.h"
//#include "rsc.h"
#include "record.h"

#if 0
static struct storage_dev_meta sd_meta = 
{
    .dev_type = DEV_SD_TYPE,
    .dev_subtype = DEV_SUB_SDIO,
    .fs_type = FS_VFAT,
    .max_num = 1,
    .prev_devid = 0,
    .mpoint = "/mnt",

    .filter = cont_filter,
    .delter = cont_delter,
};
#endif
int _str_preprocess(struct record_frame_info *frame,unsigned char *source)
{
    if(frame==NULL || source == NULL)
	return 0;

    frame->len = rand()%8192;
    frame->pts = 0;
    frame->index = 0;
    frame->flag = 0;

    if(frame->size>frame->len)
	memcpy(frame->addr,source,frame->len);
    else
    {
	frame->len = frame->size;
	memcpy(frame->addr,source,frame->len);
    }

    frame->flag = 1;
    frame->index++;
    return 0;
}

static int create_sink_name(int chn,struct record_sink *recsink, int mode)
{
    char dirname[64] = {0};
    struct tm *nowtime;
    struct tm mytm;

    nowtime = localtime_r(&recsink->ctime,&mytm);
    snprintf(dirname,sizeof(dirname), "%s/%04d%02d%02d", recsink->mpoint, 
	    nowtime->tm_year+1900,nowtime->tm_mon+1, nowtime->tm_mday);

    if (access(dirname, 0) && mkdir(dirname, S_IRWXU | S_IRWXG | S_IRWXO)) 
    {
	SLOG(ERR, "%s doesnot exist.\n", dirname);
	return -1;
    }

    sprintf(recsink->sname, "%s/%02d%02d%02d_%d.str", dirname, 
	    nowtime->tm_hour, nowtime->tm_min, nowtime->tm_sec, chn);

    /// avoid same record file exists
    remove(recsink->sname);

    return 0;
}
RSC_SINK_HANDLE _str_init_sink(int chn,struct record_sink *recsink,
	struct rsc_stream_confset *media,struct rsc_mode_attr *mode)
{
    if(recsink==NULL || mode==NULL)
    {
	SLOG(ERR,"invalid params!\n");
	return NULL;
    }
    if(create_sink_name(chn,recsink,mode->mode)<0)
    {
	SLOG(ERR,"create_sink_name fail!\n");
	return NULL;
    }
    FILE *fp = fopen(recsink->sname,"wb");
    SLOG(PRI,"open sink:%s <handle:%p>\n",recsink->sname,fp);
    return fp;
}

int _str_fill_sink(RSC_SINK_HANDLE handle,int stream,struct record_frame_info *frame)
{
    FILE *fp = (FILE*)handle;

    SLOG(PRI,"fill sink:handle[%p],stream[%d],frame len[%d]!\n",handle,stream,frame->len);
    fwrite(frame->addr,1,frame->len,fp);
    return 0;
}

int _str_exit_sink(RSC_SINK_HANDLE handle)
{
    FILE *fp = (FILE*)handle;

    SLOG(PRI,"exit sink:handle[%p]!\n",handle);
    fflush(fp);
    fclose(fp);
    return 0;
}

static unsigned char _strsrc[8192]={0};
static struct rsc_channel_attr rec_chnattr = 
{
    .chn = 0,
    .runflag = 1,
    .onstart = 0,
    .chn_temp = 0,
    .unit_time_limit = 60,
    .unit_size_limit = 800*1024*1024,
    .modeattr = {.mode = REC_MODE_AUTO,},
    .vstream = {1,_strsrc,_str_preprocess,NULL,512000},
    .astream = {1,_strsrc,_str_preprocess,NULL,64000},
    .mstream = {1,_strsrc,_str_preprocess,NULL,1024},
    .sink = {_str_init_sink,_str_fill_sink,_str_exit_sink},
};

int runflag = 1;
struct log_module log_conf = 
{ 	
    .log_path = "rsc20.log",
    .max_size = 512*1024,
    .fp = NULL,
    .mutex = PTHREAD_MUTEX_INITIALIZER,
};

void sigexit(int signo)
{
    runflag = 0;
}

#if 0
int rsc_process_init(void)
{
    int ret = 0, prev_id = 0;
    char mpoint[64]={0};

    ret = rsc_init_storage(&sd_meta);
    if(ret < 0)
    {
	SLOG(ERR,"rsc_init_storage err,ret = %d\n",ret);
	return -1;
    }
    prev_id = rsc_exception_init(NULL,sd_meta.max_num,mpoint);
    if(prev_id>=0)
	rsc_set_prev_devid(prev_id);

    SLOG(PRI,"rsc_process_init success!\n");
    return 0;
}

int main(int argc, char *argv[])
{
    int ret = 0;
    pthread_t storage_tid;

    rsc_process_init();

    char mpoint[64]={0};
    ret = pthread_create(&storage_tid,NULL,rsc_storage_process,NULL);
    if(ret)
    {
	SLOG(ERR,"create rsc_storage_process thread error:%s\n",strerror(ret));
	ret = -1;
	return ret;
    }

    while(runflag && rsc_get_avail_dev(0,mpoint)<0) 
	sleep(2);

    SLOG(PRI,">>>>>start to record process thread...\n");
    rsc_rec_init();

    /* create record process threads */
    ret = rsc_chn_create(0,&rec_chnattr);
    if(ret < 0)
    {
	SLOG(ERR,"rsc_chn_create chn[%d] fail!\n");
	runflag = 0;
    }
    else rsc_chn_start(0);

    while(runflag)
    {
	sleep(1);
    }

    rsc_chn_stop(0);
    rsc_chn_destroy(0);

    rsc_rec_exit();
    SLOG(PRI,"exit record ...\n");
    rsc_exit_storage();
    SLOG(PRI,"exit storage...\n");
    pthread_join(storage_tid,NULL);

    return ret;
}
#endif

int main(int argc, char *argv[])
{
    int ret = 0;

    signal(SIGINT,sigexit);

    SLOG(PRI,">>>>>start to record process thread.\n");
    rsc_rec_init();

    /* create record process threads */
    ret = rsc_chn_create(0,&rec_chnattr);
    if(ret < 0)
    {
	SLOG(ERR,"rsc_chn_create chn[%d] fail!\n");
	runflag = 0;
    }
    else rsc_chn_start(0);

    while(runflag)
    {
	sleep(1);
    }

    rsc_rec_exit();
    SLOG(PRI,"<<<exit record pthread.\n");

    return ret;
}

